
#include "DebugCanvas.h"


GLuint		cDBDraw::shader	= UNDEF;
GLuint		cDBDraw::vbo	= UNDEF;
GLuint		cDBDraw::pm_location = UNDEF;
GLfloat*	cDBDraw::buffer	= nullptr;
GLuint		cDBDraw::b_size	= UNDEF;
GLuint		cDBDraw::b_used	= UNDEF;
cGSCamera*  cDBDraw::camera	= nullptr;


void cDBDraw::init(GLuint buffer_size, cGSCamera* cam)
{
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

	// load shader
	shader = cRHResourceHandler::getOGLShaderFromFile("debug_shader");

	// fill buffer
	b_size = buffer_size;
	b_used = 0;
	buffer = new GLfloat[b_size * 2];

	// create vbo
	glGenBuffers(1, &vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferData(GL_ARRAY_BUFFER, buffer_size * 2 * sizeof(GLfloat), buffer, GL_DYNAMIC_DRAW);
    
    glEnableVertexAttribArray(ATTRIB_POSITION);
	glVertexAttribPointer(ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), BUFFER_OFFSET(0));
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    
	// camera
	camera = cam;
	glUseProgram(shader);
	pm_location = glGetUniformLocation(shader, "p_matrix");
	glUseProgram(0);
}
void cDBDraw::draw()
{
	glClear(GL_COLOR_BUFFER_BIT);

	glUseProgram(shader);
	glUniformMatrix4fv(pm_location, 1, GL_FALSE, camera->getMatrix().m);

	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferSubData(GL_ARRAY_BUFFER, 0, b_used * 2 * sizeof(GLfloat), buffer);
    
	glDrawArrays(GL_LINES, 0, b_used);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    
    glUseProgram(0);

	b_used = 0;
}

void cDBDraw::line(const float& x1, const float& y1, const float& x2, const float& y2)
{
	if (b_size < b_used + 2)
	{
		cout<<"ERROR Buffer out of range"<<endl;
	}
	else
	{
		buffer[b_used * 2]     = x1;
		buffer[b_used * 2 + 1] = y1;
		buffer[b_used * 2 + 2] = x2;
		buffer[b_used * 2 + 3] = y2;

		b_used += 2;
	}
}
void cDBDraw::line(const MVec2& v1, const MVec2& v2)
{
	if (b_size < b_used + 2)
	{
		cout<<"ERROR Buffer out of range"<<endl;
	}
	else
	{
		buffer[b_used * 2]     = v1.x;
		buffer[b_used * 2 + 1] = v1.y;
		buffer[b_used * 2 + 2] = v2.x;
		buffer[b_used * 2 + 3] = v2.y;

		b_used += 2;
	}
}

void cDBDraw::rect(const float& center_x, const float& center_y, const float& half_w, const float& half_h)
{

}
void cDBDraw::rect(const MVec2& center_v, const MVec2& half_size)
{

}

void cDBDraw::circle(const float& center_x, const float& center_y, const float& radius)
{
	if (b_size < b_used + 72)
	{
		cout<<"ERROR Buffer out of range"<<endl;
	}
	else
	{
		int step_cnt = 36;
		float step = 2 * M_PI / step_cnt;
		float ang = 0;

		for (int i=0; i<step_cnt; i++)
		{
			buffer[b_used * 2 + i * 4]     = center_x + radius * cosf(ang);			// x
			buffer[b_used * 2 + i * 4 + 1] = center_y + radius * sinf(ang);			// y
			buffer[b_used * 2 + i * 4 + 2] = center_x + radius * cosf(ang + step);			// x
			buffer[b_used * 2 + i * 4 + 3] = center_y + radius * sinf(ang + step);			// y

			ang += step;
		}

		b_used += 72;
	}
}
void cDBDraw::circle(const MVec2& center_v, const float& radius)
{
	if (b_size < b_used + 72)
	{
		cout<<"ERROR Buffer out of range"<<endl;
	}
	else
	{
		int step_cnt = 36;
		float step = 2 * M_PI / step_cnt;
		float ang = 0;

		for (int i=0; i<step_cnt; i++)
		{
			buffer[b_used * 2 + i * 4]     = center_v.x + radius * cosf(ang);			// x
			buffer[b_used * 2 + i * 4 + 1] = center_v.y + radius * sinf(ang);			// y
			buffer[b_used * 2 + i * 4 + 2] = center_v.x + radius * cosf(ang + step);			// x
			buffer[b_used * 2 + i * 4 + 3] = center_v.y + radius * sinf(ang + step);			// y

			ang += step;
		}

		b_used += 72;
	}
}